home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume15 / tpscript / part04 < prev    next >
Encoding:
Internet Message Format  |  1988-05-25  |  46.3 KB

  1. Subject:  v15i016:  Ditroff to PostScript translator, Part04/05
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Axel Mahler <axel%coma.UUCP%TUB.BITNET@mitvma.mit.edu>
  7. Posting-number: Volume 15, Issue 16
  8. Archive-name: tpscript/part04
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 4 (of 5)."
  17. # Wrapped by rsalz@fig.bbn.com on Thu May 26 13:02:27 1988
  18. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  19. if test -f './READ_ME.TOO' -a "${1}" != "-c" ; then 
  20.   echo shar: Will not clobber existing file \"'./READ_ME.TOO'\"
  21. else
  22. echo shar: Extracting \"'./READ_ME.TOO'\" \(7623 characters\)
  23. sed "s/^X//" >'./READ_ME.TOO' <<'END_OF_FILE'
  24. GENERAL REMARKS            (by Axel Mahler, axel@coma.uucp)
  25. X
  26. This is 'tpscript', a free ditroff to PostScript filter package.
  27. Tpscript was originally written by Stephen Frede who was with the
  28. University of New South Wales, Australia, when he wrote the programs.
  29. X
  30. Stephen posted the whole package to net.sources about two years ago.
  31. A while ago, I made a first attempt to repost the 'tpscript' package
  32. X(and some local improvements), but failed due to mail problems.
  33. However, I asked Stephen for permission, and this is what he answered:
  34. X
  35. X>Date: 26 Nov 86 12:24:44 +1100 (Wed)
  36. X>From: tub!unido!gris.oz!stephenf (Stephen Frede)
  37. X>To: coma!axel
  38. X>Subject: Re: posting of tpscript modifications
  39. X>
  40. X>By all means, post the modified sources. Since I posted the original
  41. X>version, I have moved from university to private industry, and the
  42. X>company I work for (Softway) now sells a much enhanced version of the
  43. X>original package, which incidentally allows external graphics objects
  44. X>to be incorporated, as well as many more features not present in the
  45. X>original version. Needless to say, the latest version is very much
  46. X>protected and will not be distributed over the net. But the first
  47. X>version was developed under an educational UNIX license, and under
  48. X>the terms of that license, any software developed must be made freely
  49. X>available (NOT public domain - no-one else can sell it). So go ahead
  50. X>and post.
  51. X>
  52. X>Thanks for checking with me - I look forward to seeing your
  53. X>modifications.
  54. X>
  55. X>By the way, if you are ever looking for UNIX software such as an
  56. X>enhanced PostScript driver or whatever, consider the advantages of
  57. X>buying from Australia - the exchange rate makes us quite cheap
  58. X>compared to European and US vendors. In fact if you send me your
  59. X>real mail address, I'll mail you some samples from the latest
  60. X>version.
  61. X>
  62. X>                        Stephen Frede
  63. X>
  64. X>                ...!seismo!softway.oz!stephenf
  65. X>
  66. X>                Softway Pty Ltd
  67. X>                P.O. Box 305
  68. X>                Strawberry Hills NSW 2012
  69. X>                AUSTRALIA
  70. X>
  71. X>                Phone +61 2 698 2322
  72. X>
  73. X>
  74. X>
  75. X
  76. X(Sorry that it took so long to really repost the stuff.)
  77. X
  78. X
  79. ABOUT THIS DISTRIBUTION
  80. X
  81. There's a main Makefile (I never used it), a shell script that facilitates
  82. the invocation of ditroff (I never used it either) and three directories:
  83. X
  84. X  - opscript: contains a plain ascii to PostScript conversion program
  85. X    (lpscript), and a bitmap to PostScript conversion program (ipscript).
  86. X    'lpscript' is suitable for use as an output filter for the
  87. X    lineprinter spooler system. 'ipscript' has seldomly been used
  88. X    and (if I recall it right) caused some trouble. 
  89. X
  90. X  - tpscript: contains the ditroff to PostScript conversion program,
  91. X    'tpscript'. We use 'tpscript' extensively, literally every day.
  92. X    The operating environment we have is a MicroVAX II, running
  93. X    4.3BSD with DWB 1.0 (or 1.2, I'm not certain) (di)troff, and 
  94. X    an Apple LaserWriter Plus. However, there's nothing BSD specific
  95. X    that would keep 'tpscript' from running on any sensible Unix
  96. X    system. 
  97. X    The subdirectory tpscript/devalw contains the font width tables
  98. X    for the standard-fonts. 
  99. X
  100. X  - pscript: contains a collection of PostScript source files. These
  101. X    files are either demos/samples or little utilities for producing
  102. X    font descriptions or page setups.
  103. X
  104. X
  105. IMPRESSION / REVIEW OF TPSCRIPT    
  106. X
  107. X'tpscript' is a great piece of software, and we are most gratefull to
  108. Stephen Frede for writing and publishing it. We have used it on a daily
  109. basis for about two years now, and are nothing but satisfied. (In fact,
  110. some colleagues at our department, who distrusted 'netware', and kept
  111. faith in 'supported products', had a lot more trouble with a major
  112. product in the field on a SUN 3 network.) 
  113. X
  114. I have a vague memory of a problem with our troff, not being able
  115. to hold enough font slots. This imposed a hard limit on the number
  116. of different types accessible from within a troff source file. We
  117. fixed that in our troff version (DWB 1.0 or so). I hope this gotcha
  118. is fixed with more recent releases of ditroff.
  119. X
  120. X
  121. XFEATURES
  122. X
  123. XFeatures of 'ipscript' and 'lpscript' are described in corresponding 
  124. manual entries. 'tpscript' is used as a filter, i.e. it reads its input
  125. from stdin and sends its output to stdout. The fonts used are the most
  126. commonly available on PostScript devices: Times, Helvetica and Courier.
  127. With some fiddling around it is possible to add support for other fonts
  128. X(we did that for the Bookman family of fonts).
  129. X
  130. Besides some minor fixes to the program, the most notable enhancement
  131. we added with respect to the original 'tpscript' version is the 
  132. X'E' directive. This directive allows to specify a unix command (with 
  133. arguments) to be invoked by 'tpscript', and insert the output of
  134. that command into the output stream of 'tpscript'. The 'E' directive
  135. facilitates inclusion, and appropriate scaling of externally created
  136. PostScript images (e.g. MacDraw or GemDraw) in troff-formatted documents.
  137. X_______________________________________________________________________________
  138. X| The typical use of this feature is illustrated by a macro that we           |
  139. X| wrote for this purpose (to be used with ms):                      |
  140. X|                                           |
  141. X| .nr Ph 1        \" Initialize picture-numbering-              |
  142. X| .nr Pn 0        \"            registers              |
  143. X| .if '\\*(Fg'' .ds Fg Abb.                              |
  144. X| .de Pc    \" Insert Picture --- .Pc title height filename alignment     |
  145. X| .KS                \" ms dependent keep                  |
  146. X| .sp \\$2+2v            \" vertical space for picture (2 lines frame) |
  147. X| .if !\\n(Ph=\\n(H1 \{ .nr Ph \\n(H1 \" if new chapter - save chapter number |
  148. X| .nr Pn 0 \}            \"    - initialize Picture-number          |
  149. X| .nr Pn \\n(Pn+1            \" increase picture-number          |
  150. X| .ce                                           |
  151. X| \f3\*(Fg \\n(Ph.\\n(Pn.\f1 \\$1    \" write picture Title              |
  152. X| .KE                \" release keep                      |
  153. X| .if !'\\$3'' \{            \" if a filename is given          |
  154. X| .if \\n(.P \{            \" and if page should be printed          |
  155. X| .nr Vp \\n(nl-\\$2-2v        \" In,Vp upper left corner of picture          |
  156. X| .nr In \\n(.o-32+\\n(.i        \" 32 is a LW+-correction          |
  157. X| .nr He \\$2            \" Picture height given by caller          |
  158. X| .nr Wi \\n(.l-\\n(.i        \" Picture width (line len. - cur. indent)    |
  159. X| \!E /usr/local/lib/gem2ps -V\\n(Vp -I\\n(In -H\\n(He -W\\n(Wi -A\\$4 \\$3   |
  160. X| .rr Vp                                      |
  161. X| .rr In                                      |
  162. X| .rr He                                      |
  163. X| .rr Wi                                      |
  164. X| \}                                          |
  165. X| \}                                          |
  166. X| .br                                          |
  167. X| ..                                          |
  168. X|_____________________________________________________________________________|
  169. X
  170. X
  171. INSTALLATION AND CONFIGURATION
  172. X
  173. There are two important entries in 'tpscript's Makefile: 'tpscript' and
  174. X'tpsgem'. "make tpscript" will produce the default tpscript version, just
  175. a ditroff to PostScript filter. It includes full support for PIC but no
  176. explicit support for any kind of externally generated PostScript code.
  177. If you "make tpsgem", you'll obtain a slightly different version of
  178. X'tpscript', including a specially modified PostScript prolog supporting
  179. PostScript images produced by 'gem2ps', our local GEM metafile to 
  180. PostScript conversion utility (this is a variant of the program 'mfps'
  181. which has been posted to comp.sys.atari.st). 'tpsgem' has no support
  182. for PIC graphics ! 
  183. X
  184. X> In case you want to include images produced on a Mac, you'll have to
  185. X> modify 'tpscript.c' (contains most of the prolog). Basically, you'll have
  186. X> to swap 'Gem2PsDict' with an equivalent 'LaserPrep'.
  187. X
  188. This situation is kind of unsatisfying, but for me, there has always
  189. been some other task that had to be accomplished. It would clearly be
  190. desirable to have some sort of library for various PostScript prologs
  191. that would be selected depending on an option. Maybe somebody finds
  192. the time to add this to the program.
  193. X
  194. END_OF_FILE
  195. if test 7623 -ne `wc -c <'./READ_ME.TOO'`; then
  196.     echo shar: \"'./READ_ME.TOO'\" unpacked with wrong size!
  197. fi
  198. # end of './READ_ME.TOO'
  199. fi
  200. if test -f './opscript/ipscript.c' -a "${1}" != "-c" ; then 
  201.   echo shar: Will not clobber existing file \"'./opscript/ipscript.c'\"
  202. else
  203. echo shar: Extracting \"'./opscript/ipscript.c'\" \(9061 characters\)
  204. sed "s/^X//" >'./opscript/ipscript.c' <<'END_OF_FILE'
  205. X/*
  206. X *    ipscript.c - version 3.2
  207. X *
  208. X *    Convert bitmap image to postscript
  209. X *
  210. X *        - Stephen Frede, UNSW, Australia (stephenf@elecvax.oz)
  211. X *            ...!seismo!munnari!elecvax!stephenf
  212. X *        - fixes MWR, UNSW (michaelr@elecvax.oz)
  213. X */
  214. X
  215. X#ifndef    lint
  216. static char id[] = "ipscript - version 3.2; UNSW, Australia";
  217. X#endif    lint
  218. X
  219. X#include    <stdio.h>
  220. X#include    "pscript.h"
  221. X
  222. X/* default values for the input bitmap data */
  223. X#define    N_SCANSPERIMAGE    256    /* no. scan lines */
  224. X#define    N_PIXELSPERSCAN    256    /* pixels per scanline */
  225. X#define    N_SCANRES    8    /* no. bits per pixel (input) */
  226. X#define    PAPERWIDTH    19.3    /* width (short axis) of paper (cm) */
  227. X#define    PAPERLENGTH    28.3    /* length (long axis) of paper (cm) */
  228. X
  229. X/* possible input formats */
  230. X#define    I_BYTE        'b'
  231. X#define    I_HEX        'x'
  232. X
  233. X#define    BITSINBYTE    8
  234. X
  235. int    ScansPerImage = N_SCANSPERIMAGE,    /* no. lines in image */
  236. X    PixelsPerScan = N_PIXELSPERSCAN,    /* no. pixels in each line */
  237. X    scanres = N_SCANRES,        /* input resolution (no. grey levels) */
  238. X    CellsPerInch = 60,        /* halftone cells/inch */
  239. X    outres = 8,            /* 2^outres output grey levels */
  240. X    CellRotation = 45,        /* halftone cell rotation */
  241. X    rotation = 0,            /* image rotation */
  242. X    headerskip = 0,            /* no. bytes to skip at start */
  243. X    greyoffset = 0,            /* brightness */
  244. X    PaperType =
  245. X#ifdef    ALW
  246. X        PT_A4,
  247. X#else
  248. X        PT_DEFAULT,
  249. X#endif    ALW
  250. X    inpformat = I_BYTE;        /* format of input data */
  251. float    aspect = 1.5,        /* aspect ratio (x:y) */
  252. X    width = 0.0,        /* output width (cm) */
  253. X    height = 0.0;        /* output height (cm) */
  254. bool    ManualFeed = FALSE,    /* manual or auto (paper tray) feed */
  255. X    NegativeImage = FALSE;    /* reverse black and white */
  256. X
  257. double    atof();
  258. X
  259. X/* ARGSUSED */
  260. main(argc, argv)
  261. int    argc;
  262. char    **argv;
  263. X{
  264. X    char    c;
  265. X    bool    filesgiven = FALSE,
  266. X        status = 0;
  267. X
  268. X    postr = stdout;
  269. X    ScansPerImage = N_SCANSPERIMAGE;
  270. X    PixelsPerScan = N_PIXELSPERSCAN;
  271. X    argv++;        /* skip command name */
  272. X
  273. X    while(*argv)
  274. X    {
  275. X        if(**argv == '-')
  276. X        {
  277. X            (*argv)++;    /* skip the '-' */
  278. X            c = **argv;    /* command arg */
  279. X            (*argv)++;    /* skip arg letter */
  280. X            switch(c)
  281. X            {
  282. X            case 'i':    /* input format */
  283. X                if(**argv == 'b')
  284. X                    inpformat = I_BYTE;
  285. X                else if(**argv == 'x')
  286. X                    inpformat = I_HEX;
  287. X                else
  288. X                {
  289. X                    fprintf(stderr, "input format (-i option) only allows 'b' or 'x'\n");
  290. X                    status++;
  291. X                    break;
  292. X                }
  293. X                (*argv)++;
  294. X                if(**argv == '\0')
  295. X                {
  296. X                    fprintf(stderr, "input format - expected scan resolution (bits) after `-%c'\n", (*argv)[-1]);
  297. X                    status++;
  298. X                    break;
  299. X                }
  300. X                scanres = atoi(*argv);
  301. X                if(scanres < 1 || scanres > 8)
  302. X                {
  303. X                    fprintf(stderr, "input format: illegal scan resolution must be in range 1 - 8\n");
  304. X                    status++;
  305. X                }
  306. X                break;
  307. X
  308. X            case 's':
  309. X                headerskip = atoi(*argv);
  310. X                break;
  311. X
  312. X            case 'g':    /* grey offset (brightness) */
  313. X                greyoffset = atoi(*argv);
  314. X                break;
  315. X
  316. X            case 'b':    /* bits resolution out */
  317. X                outres=atoi(*argv);
  318. X                if(outres != 1 && outres != 2 &&
  319. X                    outres != 4 && outres != 8)
  320. X                {
  321. X                    fprintf(stderr,
  322. X                        "Illegal output resolution - must be 1, 2, 4 or 8 bits\n");
  323. X                    status++;
  324. X                }
  325. X                break;
  326. X
  327. X            case 'y':    /* no. scan lines input */
  328. X                ScansPerImage=atoi(*argv);
  329. X                break;
  330. X
  331. X            case 'x':    /* pixels per scanline */
  332. X                PixelsPerScan = atoi(*argv);
  333. X                break;
  334. X
  335. X            case 'a':    /* aspect ratio */
  336. X                aspect = atof(*argv);
  337. X                break;
  338. X
  339. X            case 'w':    /* width (cm) */
  340. X                width = atof(*argv);
  341. X                break;
  342. X
  343. X            case 'h':    /* height (cm) */
  344. X                height = atof(*argv);
  345. X                break;
  346. X
  347. X            case 'f':    /* output pixels/inch */
  348. X                CellsPerInch = atoi(*argv);
  349. X                break;
  350. X
  351. X            case 'p':    /* pixel rotation */
  352. X                CellRotation = atoi(*argv);
  353. X                break;
  354. X
  355. X            case 'r':    /* image rotation */
  356. X                if(**argv)
  357. X                    rotation = atoi(*argv);
  358. X                else
  359. X                    rotation = 90;
  360. X                break;
  361. X
  362. X            case 'L':    /* 'legal' paper size */
  363. X                PaperType = PT_LEGAL;
  364. X                break;
  365. X
  366. X            case 'n':    /* negative image */
  367. X                NegativeImage = TRUE;
  368. X                break;
  369. X
  370. X            case 'S':    /* manual feed */
  371. X                ManualFeed = TRUE;
  372. X                break;
  373. X
  374. X            default:
  375. X                fprintf(stderr, "Unknown option '%c'\n", c);
  376. X                status++;
  377. X            }
  378. X        }
  379. X        else
  380. X        {
  381. X            if(status)
  382. X                usage();
  383. X            filesgiven = TRUE;
  384. X            status += DoImage(*argv);
  385. X        }
  386. X        argv++;
  387. X    }
  388. X    if(status && ! filesgiven)
  389. X        usage();
  390. X    if(! filesgiven)
  391. X        status += DoImage("-");
  392. X
  393. X    exit(status);
  394. X    /* NOTREACHED */
  395. X}
  396. X
  397. char    *usagetab[] = {
  398. X    "Usage: ipscript option file ...",
  399. X    "valid options:",
  400. X    "\t-r[angle]        output image rotation (degrees)",
  401. X    "\t-wWidth            output image width (in cm)",
  402. X    "\t-hHeight        output image height (in cm)",
  403. X    "\t-aAspect        aspect ratio (width/height)",
  404. X    "\t-yScanlines        no. scan lines in input",
  405. X    "\t-xScanlength        no. pixels in an input scan line",
  406. X    "\t-iFormat        input format: {'b'|'x'}bitsresolution",
  407. X    "\t-sSkip            no. bytes header to skip",
  408. X    "\t-gGrey            output grey level offset (signed)",
  409. X    "\t-bbits            output resolution = 2^bits greylevels",
  410. X    "\t-fFrequency        output frequency (pixels/inch)",
  411. X    "\t-pAngle            pixel grid rotation (degrees)",
  412. X    "\t-fFrequency        output frequency (dots/inch)",
  413. X    "\t-n            negative image",
  414. X    "\t-S            Use manual feed",
  415. X    (char *) 0
  416. X};
  417. X
  418. usage()
  419. X{
  420. X    char    **p;
  421. X
  422. X    p = usagetab;
  423. X    while(*p)
  424. X        fprintf(stderr, "%s\n", *p++);
  425. X    exit(1);
  426. X    /* NOTREACHED */
  427. X}
  428. X
  429. X/* postscript initialisation for options currently in effect
  430. X * Assumes default LaserWriter conditions (ie start of job)
  431. X */
  432. init(filename, BytesPerScan)
  433. char    *filename;
  434. int    BytesPerScan;
  435. X{
  436. X    pcomminit(0.0, (float) rotation, PaperType, ManualFeed,
  437. X        "", filename, "ipscript bit image");
  438. X    fprintf(postr, "gsave %d %d translate\n", rotation == 0 ? 25 : 18,
  439. X                          rotation == 0 ? 0  : 5);
  440. X
  441. X    if(height == 0.0 && width == 0.0)
  442. X        width = rotation == 0 ? PAPERWIDTH : PAPERLENGTH;
  443. X    if(height == 0.0)
  444. X        height = width / aspect;
  445. X    else if(width == 0.0)
  446. X        width = height * aspect;
  447. X    fprintf(postr, "%.1f %.1f scale\n", width * PU_CM, height * PU_CM);
  448. X
  449. X    fprintf(postr, "0 setlinewidth\n");
  450. X    fprintf(postr, "/picstr %d string def\n", BytesPerScan);
  451. X    fprintf(postr, "/doimage {\n");
  452. X    fprintf(postr, "%d %d %d [ %d 0 0 %d 0 %d ]\n",
  453. X        PixelsPerScan, ScansPerImage, outres,
  454. X        PixelsPerScan, - ScansPerImage, ScansPerImage);
  455. X    fprintf(postr, "{ currentfile picstr readhexstring pop } image\n");
  456. X    fprintf(postr, "} def\n");
  457. X    if(CellsPerInch != PD_PFREQUENCY || CellRotation != PD_PROTATION)
  458. X        fprintf(postr, "%d %d {dup mul exch dup mul add 1 exch sub} setscreen\n", CellsPerInch, CellRotation);
  459. X    if(NegativeImage)
  460. X        fprintf(postr, "{1 exch sub} settransfer\n");
  461. X}
  462. X
  463. DoImage(filename)
  464. char    *filename;
  465. X{
  466. X    register int    outval,
  467. X            PixelInByte,
  468. X            ByteInScan,
  469. X            PixelInScan,
  470. X            ScanInImage;
  471. X    int        div,
  472. X            inval,
  473. X            max;
  474. X    FILE        *istr;
  475. X    int        BytesPerScan;    /* no. bytes/scanline output */
  476. X    int        PixelsInByte;    /* no. pixels/byte output */
  477. X    bool        OutRange = FALSE;
  478. X
  479. X    if(strcmp(filename, "-") == 0)
  480. X        istr = stdin;
  481. X    else if((istr = fopen(filename, "r")) == NULL)
  482. X    {
  483. X        perror(filename);
  484. X        return(1);
  485. X    }
  486. X
  487. X    PixelsInByte = BITSINBYTE / outres;
  488. X    BytesPerScan = (PixelsPerScan + PixelsInByte - 1) / PixelsInByte;
  489. X
  490. X    init(filename, BytesPerScan);
  491. X    max = 1 << scanres;
  492. X    div = scanres - outres;
  493. X
  494. X    fprintf(postr, "%% Resolution: %d bits\n",
  495. X        outres);
  496. X    fprintf(postr, "(bit image start ...\\n) ps\n");
  497. X    fprintf(postr, "%%%%EndProlog\n");
  498. X    fprintf(postr, "%%%%Page 1 1\n");
  499. X
  500. X    fprintf(postr, "doimage\n");
  501. X
  502. X    for(ByteInScan = 0; ByteInScan < headerskip; ByteInScan++)
  503. X        getc(istr);
  504. X
  505. X    for(ScanInImage = 0; ScanInImage < ScansPerImage; ScanInImage++)
  506. X    {
  507. X        for(ByteInScan = 0, PixelInScan = 0;
  508. X            ByteInScan < BytesPerScan; ByteInScan++)
  509. X        {
  510. X            outval = 0;
  511. X            /* build up an output byte */
  512. X            for(PixelInByte = 0;
  513. X                PixelInByte < PixelsInByte && PixelInScan < PixelsPerScan;
  514. X                PixelInByte++, PixelInScan++)
  515. X            {
  516. X                if(inpformat == I_BYTE)
  517. X                    inval = getc(istr);
  518. X                else
  519. X                {    /* I_HEX */
  520. X                    if(scanres <= 4)
  521. X                        fscanf(istr, "%1X", &inval);
  522. X                    else
  523. X                        fscanf(istr, "%2X", &inval);
  524. X                }
  525. X                if(feof(istr))
  526. X                {
  527. X                    fprintf(stderr, "Error: insufficient input\n");
  528. X                    return(1);
  529. X                }
  530. X                if(greyoffset)
  531. X                inval += greyoffset;
  532. X                if(inval < 0)
  533. X                {
  534. X                    inval = 0;
  535. X                    OutRange = TRUE;
  536. X                }
  537. X                else if(inval >= max)
  538. X                {
  539. X                    inval = max-1;
  540. X                    OutRange = TRUE;
  541. X                }
  542. X                if(div >= 0)
  543. X                    outval = (outval << outres) | (inval >> div);
  544. X                else
  545. X                    outval = (outval << outres) | (inval << -div);
  546. X            }
  547. X            /* make up a whole byte at the end of a scan line */
  548. X            for(; PixelInByte < PixelsInByte; PixelInByte++)
  549. X                outval = outval << outres;
  550. X            /* do a little bit of formatting to make it readable */
  551. X            if(ByteInScan % 10 == 0)
  552. X                if(ByteInScan % 30 == 0) putc('\n', postr);
  553. X                else putc(' ', postr);
  554. X            fprintf(postr, "%X%X", outval >> 4, outval & 017);
  555. X        }
  556. X        /* end of a scan line */
  557. X        fprintf(postr, "\n");
  558. X    }
  559. X
  560. X    /* draw a border around the picture */
  561. X    if(NegativeImage)
  562. X        fprintf(postr, "{} settransfer\n");    /* restore transfer func */
  563. X    fprintf(postr,
  564. X        "newpath 0 0 moveto 1 0 lineto 1 1 lineto 0 1 lineto closepath stroke\n");
  565. X
  566. X    fprintf(postr, "\ngrestore\nshowpage\n");
  567. X    pcommfinish(-1, "");
  568. X    if(getc(istr) != EOF)
  569. X        fprintf(stderr,
  570. X            "Warning: input data after end of image\n");
  571. X    if(OutRange)
  572. X        fprintf(stderr,
  573. X            "Warning: input greyscale range too large - change 'i' or 'g' options\n");
  574. X    return(0);
  575. X}
  576. END_OF_FILE
  577. if test 9061 -ne `wc -c <'./opscript/ipscript.c'`; then
  578.     echo shar: \"'./opscript/ipscript.c'\" unpacked with wrong size!
  579. fi
  580. # end of './opscript/ipscript.c'
  581. fi
  582. if test -f './opscript/lpscript.c' -a "${1}" != "-c" ; then 
  583.   echo shar: Will not clobber existing file \"'./opscript/lpscript.c'\"
  584. else
  585. echo shar: Extracting \"'./opscript/lpscript.c'\" \(5717 characters\)
  586. sed "s/^X//" >'./opscript/lpscript.c' <<'END_OF_FILE'
  587. X/*
  588. X *    lpscript - version 3.1
  589. X *
  590. X *    Convert plain text to postscript
  591. X *
  592. X *        - Stephen Frede, UNSW, Australia (stephenf@elecvax.oz)
  593. X *            ...!seismo!munnari!elecvax!stephenf
  594. X */
  595. X
  596. X#ifndef    lint
  597. static char id[] = "lpscript - version 3.1; Stephen Frede, UNSW, Australia";
  598. X#endif    lint
  599. X
  600. X#include    <stdio.h>
  601. X#include    "pscript.h"
  602. X
  603. X#define    PAGEOFFSET    (1.0*PU_CM)
  604. X#define    FONTSIZE    10.0        /* default font size (in points) */
  605. X#define    TABSIZE        8
  606. X#define    FONT        "Courier"
  607. X#define    DOUBLESPACE    1.8        /* line spacing for double spacing */
  608. X
  609. X
  610. char    usage[] = "Valid lpscript options:\n\t-o[offset]\n\t-r[rotation]\n\
  611. X\t-s[fontsize]\n\t-a[fontaspect]\n\t-p[pitch]\n\t-f[font]\n\t-t[tabsize]\n\
  612. X\t-h[horizontal_spacing]\n\t[-S]\t(manual feed)\n\t[-L]\t(legal paper type)\n";
  613. int    tabsize = TABSIZE;        /* in character positions */
  614. X
  615. double    atof();
  616. X
  617. X/* ARGSUSED */
  618. main(argc, argv)
  619. int    argc;
  620. char    **argv;
  621. X{
  622. X    int    status = 0;    /* exit status (no. errors occured) */
  623. X    float    pageoffset = 18.0,
  624. X        fontsize = FONTSIZE,
  625. X        aspect = 1.0,
  626. X        linepitch = 0,
  627. X        spacing = 0.0,
  628. X        rotation = PD_ROTATION;
  629. X    char    *fontname = FONT;
  630. X    FILE    *istr;
  631. X    bool    manualfeed = FALSE,
  632. X        doublespace = FALSE;
  633. X    int    pagetype    =
  634. X#ifdef    ALW
  635. X                PT_A4;
  636. X#else    ALW
  637. X                PT_DEFAULT;
  638. X#endif    ALW
  639. X
  640. X    postr = stdout;
  641. X    argv++;        /* skip program name */
  642. X    while(*argv && **argv == '-')
  643. X    {
  644. X        char    c;
  645. X
  646. X        (*argv)++;    /* skip the '-' */
  647. X        c = **argv;    /* option letter */
  648. X        (*argv)++;    /* skip option letter */
  649. X        switch(c)
  650. X        {
  651. X            case 'o':    /* offset */
  652. X                if(**argv == '\0')
  653. X                    pageoffset = PAGEOFFSET;
  654. X                else
  655. X                    pageoffset = atof(*argv) * PU_CM;
  656. X                break;
  657. X
  658. X            case 'r':    /* rotation */
  659. X                if(**argv == '\0')
  660. X                    rotation = 90.0;
  661. X                else
  662. X                    rotation = atof(*argv);
  663. X                break;
  664. X
  665. X            case 'p':    /* pitch (line spacing) */
  666. X                if(**argv == '\0')
  667. X                    doublespace = TRUE;
  668. X                else
  669. X                    linepitch = atof(*argv);
  670. X                break;
  671. X
  672. X            case 's':    /* font size */
  673. X                if(**argv == '\0')
  674. X                    fontsize = 12.0;
  675. X                else
  676. X                    fontsize = atof(*argv);
  677. X                break;
  678. X
  679. X            case 't':    /* tab size */
  680. X                if(**argv == '\0')
  681. X                    tabsize = 4;
  682. X                else
  683. X                    tabsize = (int) atof(*argv);
  684. X                break;
  685. X
  686. X            case 'f':    /* font */
  687. X                if(**argv == '\0')
  688. X                    fontname = "Times-Roman";
  689. X                else
  690. X                    fontname = *argv;
  691. X                break;
  692. X
  693. X            case 'h':    /* horizontal spacing */
  694. X                if(**argv == '\0')
  695. X                    spacing = 0.25;
  696. X                else
  697. X                    spacing = atof(*argv);
  698. X                break;
  699. X
  700. X            case 'a':    /* character aspect ratio */
  701. X                if(**argv == '\0')
  702. X                    aspect = 1.0;
  703. X                else
  704. X                    aspect = atof(*argv);
  705. X                break;
  706. X
  707. X            case 'S':    /* manual feed */
  708. X                manualfeed = TRUE;
  709. X                break;
  710. X
  711. X            case 'L':    /* legal paper type */
  712. X                pagetype = PT_LEGAL;
  713. X                break;
  714. X
  715. X            default:
  716. X                fprintf(stderr, "Unknown option: '%c'\n", c);
  717. X                status++;
  718. X                break;
  719. X        }
  720. X        argv++;
  721. X    }
  722. X    if(status)
  723. X    {
  724. X        fprintf(stderr, usage);
  725. X        exit(status);
  726. X        /* NOTREACHED */
  727. X    }
  728. X    if(doublespace)
  729. X        linepitch = fontsize * DOUBLESPACE;
  730. X    if(linepitch == 0)
  731. X        linepitch = fontsize;
  732. X    spacing *= fontsize;
  733. X    init(fontsize, aspect, pageoffset, linepitch, rotation, fontname,
  734. X        spacing, manualfeed, pagetype);
  735. X    if(! *argv)
  736. X    {
  737. X        fprintf(postr, "(stdin ...\\n) ps\n");
  738. X        process(stdin);
  739. X    }
  740. X    else while(*argv)
  741. X    {
  742. X        if((istr = fopen(*argv, "r")) == NULL)
  743. X        {
  744. X            perror(*argv);
  745. X            status++;
  746. X        }
  747. X        else
  748. X        {
  749. X            fprintf(postr, "('%s' ...\\n) ps\n", *argv);
  750. X            process(istr);
  751. X            fclose(istr);
  752. X        }
  753. X        argv++;
  754. X    }
  755. X    pcommfinish(-1, (char *)0);
  756. X    putc('\004', postr);
  757. X    exit(status);
  758. X    /* NOTREACHED */
  759. X}
  760. X
  761. process(istr)
  762. XFILE    *istr;
  763. X{
  764. X    register int    ch;
  765. X    register int    x;    /* used for tab calculations */
  766. X    register int    prefix;
  767. X
  768. X    x = 0;
  769. X    prefix = 0;
  770. X    while((ch=getc(istr)) != EOF)
  771. X    {
  772. X        if(!prefix)
  773. X        {
  774. X            putc('(', postr);
  775. X            prefix = 1;
  776. X        }
  777. X        if(ch < ' ' && ch != '\t' && ch != '\n' && ch != '\r' && ch != '\f')
  778. X            ch = '?';
  779. X        switch(ch)
  780. X        {    
  781. X        case '\t':
  782. X            {
  783. X            int    n = x + tabsize - (x % tabsize);
  784. X
  785. X            while(x < n)
  786. X                pch(' '), x++;
  787. X            }
  788. X            break;    
  789. X        case '\n':
  790. X            x = 0;
  791. X            fprintf(postr, ")n\n");
  792. X            prefix = 0;
  793. X            break;
  794. X        case '\r':
  795. X            x = 0;
  796. X            fprintf(postr, ")r\n");
  797. X            prefix = 0;
  798. X            break;
  799. X        case '\f':
  800. X            x = 0;
  801. X            fprintf(postr, ")n dpage\n");
  802. X            prefix = 0;
  803. X            break;
  804. X        default:
  805. X            pch(ch);
  806. X            x++;
  807. X        }
  808. X    }
  809. X    if(prefix)
  810. X        fprintf(postr, ")n\n");
  811. X    fprintf(postr, "dpage ( ---\\n) ps\n");
  812. X}
  813. X
  814. char    *inittab[] = {
  815. X    /* current y coord */
  816. X    "/y { currentpoint exch pop } def",
  817. X
  818. X    /* var to prevent trailing blank page */
  819. X    "/dopage false def",
  820. X
  821. X    /* print a new page */
  822. X    "/dpage { dopage { page /dopage false def } if } def",
  823. X
  824. X    /* print a line then move to the next */
  825. X    "/n",
  826. X    "{ spacing 0 3 -1 roll ashow",
  827. X    "  0 y linepitch add moveto",
  828. X    "  /dopage true def",
  829. X    "  y pgbot lt { dpage } if",
  830. X    "} def",
  831. X
  832. X    /* print a line - then return to start */
  833. X    "/r",
  834. X    "{ spacing 0 3 -1 roll ashow",
  835. X    "  0 y moveto",
  836. X    "  /dopage true def",
  837. X    "} def",
  838. X
  839. X    (char *)0 };
  840. X
  841. init(fontsize, aspect, pageoffset, linepitch, rotation, fontname,
  842. X    spacing, manualfeed, pagetype)
  843. float    fontsize,
  844. X    aspect,
  845. X    pageoffset,
  846. X    linepitch,
  847. X    spacing,
  848. X    rotation;
  849. char    *fontname;
  850. bool    manualfeed;
  851. int    pagetype;
  852. X{
  853. X    register char    **p;
  854. X
  855. X    pcomminit(0.0, rotation, pagetype, manualfeed,
  856. X            fontname, (char *)0, "lpscript");
  857. X    p = inittab;
  858. X    while(*p)
  859. X        fprintf(postr, "%s\n", *p++);
  860. X    fprintf(postr, "/%s findfont [ %.1f 0 0 %.1f 0 0 ] makefont setfont\n",
  861. X        fontname, fontsize, fontsize * aspect);
  862. X    fprintf(postr, "/linepitch %.1f def\n", -linepitch);
  863. X    fprintf(postr, "/spacing %.1f def\n", spacing);
  864. X    /* subtract linespacing (add -'ve) to get top text baseline */
  865. X    fprintf(postr, "/pgtop pgtop linepitch add def\n");
  866. X    /* calculate bottom text baseline */
  867. X    fprintf(postr, "/pgbot currentfont /FontBBox get 1 get neg 1000 div %.1f mul def\n", fontsize * aspect);
  868. X    /* apply horizontal offset, if any */
  869. X    fprintf(postr, "%.1f 0 translate\n", pageoffset);
  870. X
  871. X    /* save state */
  872. X    endinit();
  873. X}
  874. END_OF_FILE
  875. if test 5717 -ne `wc -c <'./opscript/lpscript.c'`; then
  876.     echo shar: \"'./opscript/lpscript.c'\" unpacked with wrong size!
  877. fi
  878. # end of './opscript/lpscript.c'
  879. fi
  880. if test -f './opscript/pcom.c' -a "${1}" != "-c" ; then 
  881.   echo shar: Will not clobber existing file \"'./opscript/pcom.c'\"
  882. else
  883. echo shar: Extracting \"'./opscript/pcom.c'\" \(6439 characters\)
  884. sed "s/^X//" >'./opscript/pcom.c' <<'END_OF_FILE'
  885. X/* LINTLIBRARY */
  886. X/*
  887. X *    pcom.c
  888. X *
  889. X *    Some common code for programs which generate postscript.
  890. X *
  891. X *    We assume that the lineprinter software brackets jobs with EOF,
  892. X *    and possibly sets jobname etc., so we don't do it ourselves.
  893. X *    The program that calls these routines should do any necessary
  894. X *    scaling first.
  895. X *    We will set the following variables:
  896. X *    /pgtop        top of page 
  897. X *    /stm        job start time in ms
  898. X *    /spg        pages at start of job
  899. X *    /jobname    string - name of current job
  900. X *    We define the following postscript routines:
  901. X *    /mf        enable manual feed
  902. X *    /af        enable auto feed
  903. X *    /ps        print string on output stream
  904. X *    /a4        set a4 page size    (Apple LaserWriter Only)
  905. X *
  906. X */
  907. X
  908. X#include    "pscript.h"
  909. X#include    <stdio.h>
  910. X#if    VERBOSE 
  911. X#if    BSD
  912. X#include    <sys/time.h>
  913. X#else    BSD
  914. X#include    <time.h>
  915. X#endif    BSD
  916. X#if    AUSAM
  917. X#include    <passwd.h>
  918. X#else    AUSAM
  919. X#include    <pwd.h>
  920. X#endif    AUSAM
  921. X#if    SYSV
  922. X#include    <sys/utsname.h>
  923. X#endif    SYSV
  924. X#if    UNSW
  925. X#include    <table.h>
  926. X#endif    UNSW
  927. X#endif    VERBOSE
  928. X
  929. X    /* output stream on which postscript appears */
  930. XFILE        *postr = NULL;
  931. X
  932. long    time();
  933. char    *ctime(),
  934. X    *getuser(),
  935. X    *systemid();
  936. X
  937. char    *ptstr[] = {
  938. X    "",        /* default - usually determined by paper tray */
  939. X    "letter",
  940. X    "legal",
  941. X    "note",
  942. X#ifdef    ALW
  943. X    "a4",        /* on Apple LaserWriter ONLY */
  944. X#endif    ALW
  945. X};
  946. X
  947. char    *pcom0tab[] = {
  948. X    "initmatrix",
  949. X#ifdef    ALW
  950. X    "/a4 [ [300 72 div 0 0 -300 72 div -52 3436 ] 292 3365",
  951. X#ifndef ALWPLUS
  952. X    "{statusdict /jobstate (printing) put 0 setblink",
  953. X    "margins exch 157 add exch 245 add 8 div round cvi frametoroket",
  954. X    "statusdict /jobstate (busy) put 1 setblink} /framedevice load",
  955. X#endif  ALWPLUS
  956. X    "60 45 {dup mul exch dup mul add 1.0 exch sub} /setscreen load",
  957. X    "{} /settransfer load /initgraphics load /erasepage load ] cvx",
  958. X    "statusdict begin bind end readonly def",
  959. X#endif    ALW
  960. X    (char *)0
  961. X};
  962. X
  963. char    *pcom1tab[] = {
  964. X#if    VERBOSE
  965. X    /* job start time in ms */
  966. X    "/stm usertime def",
  967. X    /* remember total pages used */
  968. X    "/pgc statusdict begin pagecount end def",
  969. X#endif    VERBOSE
  970. X    /* move origin up page so bottom is bottom of imageable region */
  971. X    "clippath pathbbox pop pop exch pop 0 exch translate",
  972. X    /* save top of page */
  973. X    "clippath pathbbox /pgtop exch def pop pop pop",
  974. X#if    VERBOSE
  975. X    /* routine to print strings on output stream */
  976. X    "/ps { print flush } def",
  977. X#endif
  978. X    /* routine to print a page and begin a new one */
  979. X    /* the restore/save pair is important - it ensures that VM garbage
  980. X     * collection is done at least once every page. The user program
  981. X     * (ie lpscript, tpscript, etc.) MUST call endinit() as the
  982. X     * last part of its initialisation - this prints an initial
  983. X     * "save".
  984. X     */
  985. X    "/page { copypage erasepage restore save home } def",
  986. X    /* routine to initialise a path */
  987. X    "/home { newpath 0 pgtop moveto } def",
  988. X    /* routines to select manual or auto feed */
  989. X    "/mf { statusdict /manualfeed true put",
  990. X#ifdef    ALW
  991. X    /* fix for manual feed bug (see p. 29 Appendix D Inside LaserWriter) */
  992. X    " usertime 5000 add { dup usertime lt { pop exit } if } loop",
  993. X#endif    ALW
  994. X    " } def",
  995. X    "/af { statusdict /manualfeed false put } def",
  996. X    (char *)0
  997. X};
  998. X
  999. pcomminit(scale, rotation, papertype, manualfeed, font, title, creator)
  1000. float    rotation,
  1001. X    scale;
  1002. int    papertype;
  1003. bool    manualfeed;
  1004. char    *font,
  1005. X    *title,
  1006. X    *creator;
  1007. X{
  1008. X    register char    **ptab;
  1009. X    long        clock;
  1010. X#if    VERBOSE
  1011. X    char        *user;
  1012. X    char        jobname[100];
  1013. X#endif    VERBOSE
  1014. X
  1015. X    fprintf(postr, "%%!PS-Adobe-1.0\n");
  1016. X    time(&clock);
  1017. X#if    VERBOSE
  1018. X    user = getuser();
  1019. X    if(title)
  1020. X        strcpy(jobname, title);
  1021. X    else
  1022. X    {
  1023. X        strcpy(jobname, user);
  1024. X        strcat(jobname, "/");
  1025. X        strcat(jobname, creator);
  1026. X    }
  1027. X    fprintf(postr, "%%%%Title: %s\n", jobname);
  1028. X#endif    VERBOSE
  1029. X    fprintf(postr, "%%%%DocumentFonts: %s\n",
  1030. X        font ? font : "");
  1031. X    fprintf(postr, "%%%%Creator: %s\n", creator);
  1032. X    fprintf(postr, "%%%%CreationDate: %s", ctime(&clock));
  1033. X    fprintf(postr, "%%%%Pages: (atend)\n");
  1034. X#if    VERBOSE
  1035. X    fprintf(postr, "%%%%For: %s\n", user);
  1036. X#endif    VERBOSE
  1037. X    fprintf(postr, "%%%%EndComments\n");
  1038. X    ptab = pcom0tab;
  1039. X    while(*ptab)
  1040. X        fprintf(postr, "%s\n", *ptab++);
  1041. X    fprintf(postr, "%s\n", ptstr[papertype]);
  1042. X    if(rotation != PD_ROTATION)
  1043. X        fprintf(postr, "%.1f rotate\n", rotation);
  1044. X    if(scale != 1.0 && scale != 0.0)
  1045. X        fprintf(postr, "%.4f dup scale\n", scale);
  1046. X    ptab = pcom1tab;
  1047. X    while(*ptab)
  1048. X        fprintf(postr, "%s\n", *ptab++);
  1049. X#if    VERBOSE
  1050. X    fprintf(postr, "/jobname (%s) def\n", jobname);
  1051. X    fprintf(postr, "userdict /jobname jobname put\n");
  1052. X    fprintf(postr, "( :: '%s' :: job starts\\n) ps\n", jobname);
  1053. X#endif    VERBOSE
  1054. X    fprintf(postr, "%s\n", manualfeed ? "mf" : "af");
  1055. X}
  1056. X
  1057. endinit()
  1058. X{
  1059. X    /* this save is for the restore/save pairs in page */
  1060. X    fprintf(postr, "\nsave\n");
  1061. X    /* all variable assignments are now local to a page */
  1062. X
  1063. X    /* initialise current path - move to top of page */
  1064. X    fprintf(postr, "home\n");
  1065. X    fprintf(postr, "%%%%EndProlog\n");
  1066. X}
  1067. X
  1068. pch(ch)
  1069. int    ch;
  1070. X{
  1071. X    if(ch < ' ' || ch > '~')
  1072. X        fprintf(postr, "\\%03o", ch);
  1073. X    else
  1074. X    {
  1075. X        if(ch == '(' || ch == ')' || ch == '\\')
  1076. X            putc('\\', postr);
  1077. X        putc(ch, postr);
  1078. X    }
  1079. X}
  1080. X
  1081. pcommfinish(pages, fonts)
  1082. int pages;
  1083. char *fonts;
  1084. X{
  1085. X    fprintf(postr, "\n%%%%Trailer\n");
  1086. X#if    VERBOSE
  1087. X    fprintf(postr, "jobname ps (: Job finished:\\n) ps\n");
  1088. X    fprintf(postr, "(\\ttime (s) = ) ps usertime stm sub 1000 div ==\n");
  1089. X    fprintf(postr, "(\\tpages = ) ps statusdict begin pagecount end pgc sub == flush\n");
  1090. X    if(pages >= 0)
  1091. X        fprintf(postr, "%%%%Pages: %d\n", pages);
  1092. X#endif    VERBOSE
  1093. X    if(fonts)
  1094. X        fprintf(postr, "%%%%DocumentFonts: %s\n");
  1095. X}
  1096. X
  1097. X#if    VERBOSE
  1098. char *
  1099. getuser()
  1100. X{
  1101. X    char        *lname;
  1102. X    static char    username[100];
  1103. X#if    AUSAM
  1104. X    char        sbuf[SSIZ];
  1105. X    struct pwent    pe;
  1106. X    extern int    getpwlog();
  1107. X
  1108. X    pe.pw_limits.l_uid = getuid();
  1109. X    if(getpwlog(&pe, sbuf, sizeof(sbuf)) == PWERROR)
  1110. X        lname = (char *)0;
  1111. X    else
  1112. X        lname = pe.pw_strings[LNAME];
  1113. X    pwclose();
  1114. X    if(lname == (char *)0)
  1115. X        lname = "?";
  1116. X    strcpy(username, lname);
  1117. X
  1118. X#else    /* ! AUSAM */
  1119. X    extern    char        *getlogin();
  1120. X    extern    struct passwd    *getpwuid();
  1121. X    struct    passwd        *pwdp;
  1122. X
  1123. X    if ( ( lname = getlogin() ) != NULL )
  1124. X        strcpy( username, lname );
  1125. X    else
  1126. X    {
  1127. X        if ( ( pwdp = getpwuid( getuid() ) ) == (struct passwd *)0 )
  1128. X            sprintf( username, "User%d", getuid() );
  1129. X        else
  1130. X            strcpy( username, pwdp->pw_name );
  1131. X    }
  1132. X#endif    /* ! AUSAM */
  1133. X    strcat(username, "@");
  1134. X    strcat(username, systemid());
  1135. X    return(username);
  1136. X}
  1137. X
  1138. char *
  1139. systemid()
  1140. X{
  1141. X    static char    sysname[100] = "";
  1142. X
  1143. X#if    UNSW
  1144. X    getaddr(G_SYSNAME, sysname);
  1145. X#endif    UNSW
  1146. X
  1147. X#if    BSD
  1148. X    gethostname( sysname, sizeof(sysname) );
  1149. X#endif    BSD
  1150. X
  1151. X#if    SYSV
  1152. X    struct utsname    un;
  1153. X
  1154. X    uname(&un);
  1155. X    strcpy(sysname, un.nodename);
  1156. X#endif    SYSV
  1157. X
  1158. X    return(sysname);
  1159. X}
  1160. X#endif    VERBOSE
  1161. END_OF_FILE
  1162. if test 6439 -ne `wc -c <'./opscript/pcom.c'`; then
  1163.     echo shar: \"'./opscript/pcom.c'\" unpacked with wrong size!
  1164. fi
  1165. # end of './opscript/pcom.c'
  1166. fi
  1167. if test -f './tpscript/pcom.c' -a "${1}" != "-c" ; then 
  1168.   echo shar: Will not clobber existing file \"'./tpscript/pcom.c'\"
  1169. else
  1170. echo shar: Extracting \"'./tpscript/pcom.c'\" \(7314 characters\)
  1171. sed "s/^X//" >'./tpscript/pcom.c' <<'END_OF_FILE'
  1172. X/* LINTLIBRARY */
  1173. X/*
  1174. X *    pcom.c
  1175. X *
  1176. X *    Some common code for programs which generate postscript.
  1177. X *
  1178. X *    We assume that the lineprinter software brackets jobs with EOF,
  1179. X *    and possibly sets jobname etc., so we don't do it ourselves.
  1180. X *    The program that calls these routines should do any necessary
  1181. X *    scaling first.
  1182. X *    We will set the following variables:
  1183. X *    /pgtop        top of page 
  1184. X *    /stm        job start time in ms
  1185. X *    /spg        pages at start of job
  1186. X *    /jobname    string - name of current job
  1187. X *    We define the following postscript routines:
  1188. X *    /mf        enable manual feed
  1189. X *    /af        enable auto feed
  1190. X *    /ps        print string on output stream
  1191. X *    /a4        set a4 page size    (Apple LaserWriter Only)
  1192. X *
  1193. X */
  1194. X
  1195. X#include    "pscript.h"
  1196. X#include    <stdio.h>
  1197. X#if    VERBOSE 
  1198. X#if    BSD
  1199. X#include    <sys/time.h>
  1200. X#else    BSD
  1201. X#include    <time.h>
  1202. X#endif    BSD
  1203. X#if    AUSAM
  1204. X#include    <passwd.h>
  1205. X#else    AUSAM
  1206. X#include    <pwd.h>
  1207. X#endif    AUSAM
  1208. X#if    SYSV
  1209. X#include    <sys/utsname.h>
  1210. X#endif    SYSV
  1211. X#if    UNSW
  1212. X#include    <table.h>
  1213. X#endif    UNSW
  1214. X#endif    VERBOSE
  1215. X
  1216. X    /* output stream on which postscript appears */
  1217. XFILE        *postr = NULL;
  1218. X
  1219. long    time();
  1220. char    *ctime(),
  1221. X    *getuser(),
  1222. X    *systemid();
  1223. X
  1224. char    *ptstr[] = {
  1225. X    "",        /* default - usually determined by paper tray */
  1226. X    "letter",
  1227. X    "legal",
  1228. X    "note",
  1229. X#ifndef GEMPRINT
  1230. X#ifdef    ALW
  1231. X    "a4",        /* on Apple LaserWriter ONLY */
  1232. X#endif    ALW
  1233. X#endif GEMPRINT
  1234. X};
  1235. X
  1236. char    *pcom0tab[] = {
  1237. X    "initmatrix",
  1238. X#ifndef GEMPRINT
  1239. X#ifdef    ALW
  1240. X    "/a4 [ [300 72 div 0 0 -300 72 div -52 3436 ] 292 3365",
  1241. X#ifndef ALWPLUS
  1242. X    "{statusdict /jobstate (printing) put 0 setblink",
  1243. X    "margins exch 157 add exch 245 add 8 div round cvi frametoroket",
  1244. X    "statusdict /jobstate (busy) put 1 setblink} /framedevice load",
  1245. X#endif  ALWPLUS
  1246. X    "60 45 {dup mul exch dup mul add 1.0 exch sub} /setscreen load",
  1247. X    "{} /settransfer load /initgraphics load /erasepage load ] cvx",
  1248. X    "statusdict begin bind end readonly def",
  1249. X#endif    ALW
  1250. X#endif GEMPRINT
  1251. X    (char *)0
  1252. X};
  1253. X
  1254. char    *pcom1tab[] = {
  1255. X#if    VERBOSE
  1256. X    /* job start time in ms */
  1257. X    "/stm usertime def",
  1258. X    /* remember total pages used */
  1259. X    "/pgc statusdict begin pagecount end def",
  1260. X#endif    VERBOSE
  1261. X    /* move origin up page so bottom is bottom of imageable region */
  1262. X    "clippath pathbbox pop pop exch pop 0 exch translate",
  1263. X    /* save top of page */
  1264. X    "clippath pathbbox /pgtop exch def pop pop pop",
  1265. X#if    VERBOSE
  1266. X    /* routine to print strings on output stream */
  1267. X    "/ps { print flush } def",
  1268. X#endif
  1269. X    /* routine to print a page and begin a new one */
  1270. X    /* the restore/save pair is important - it ensures that VM garbage
  1271. X     * collection is done at least once every page. The user program
  1272. X     * (ie lpscript, tpscript, etc.) MUST call endinit() as the
  1273. X     * last part of its initialisation - this prints an initial
  1274. X     * "save".
  1275. X     */
  1276. X    "/page { copypage erasepage restore save home } def",
  1277. X    /* routine to initialise a path */
  1278. X    "/home { newpath 0 pgtop moveto } def",
  1279. X    /* routines to select manual or auto feed */
  1280. X    "/mf { statusdict /manualfeed true put",
  1281. X#ifdef    ALW
  1282. X    /* fix for manual feed bug (see p. 29 Appendix D Inside LaserWriter) */
  1283. X    " usertime 5000 add { dup usertime lt { pop exit } if } loop",
  1284. X#endif    ALW
  1285. X    " } def",
  1286. X    "/af { statusdict /manualfeed false put } def",
  1287. X    (char *)0
  1288. X};
  1289. X
  1290. pcomminit(scale, rotation, papertype, manualfeed, font, title, creator)
  1291. float    rotation,
  1292. X    scale;
  1293. int    papertype;
  1294. bool    manualfeed;
  1295. char    *font,
  1296. X    *title,
  1297. X    *creator;
  1298. X{
  1299. X    register char    **ptab;
  1300. X    long        clock;
  1301. X#if    VERBOSE
  1302. X    char        *user;
  1303. X    char        jobname[100];
  1304. X#endif    VERBOSE
  1305. X
  1306. X    fprintf(postr, "%%!PS-Adobe-1.0\n");
  1307. X
  1308. X    time(&clock);
  1309. X#if    VERBOSE
  1310. X    user = getuser();
  1311. X    if(title)
  1312. X        strcpy(jobname, title);
  1313. X    else
  1314. X    {
  1315. X        strcpy(jobname, user);
  1316. X        strcat(jobname, "/");
  1317. X        strcat(jobname, creator);
  1318. X    }
  1319. X    fprintf(postr, "%%%%Title: %s\n", jobname);
  1320. X#endif    VERBOSE
  1321. X    fprintf(postr, "%%%%DocumentFonts: %s\n",
  1322. X        font ? font : "");
  1323. X    fprintf(postr, "%%%%Creator: %s\n", creator);
  1324. X    fprintf(postr, "%%%%CreationDate: %s", ctime(&clock));
  1325. X    fprintf(postr, "%%%%Pages: (atend)\n");
  1326. X#if    VERBOSE
  1327. X    fprintf(postr, "%%%%For: %s\n", user);
  1328. X#endif    VERBOSE
  1329. X    fprintf(postr, "%%%%EndComments\n");
  1330. X
  1331. X/* This is the complementary statement for the end of pcommfinish. */
  1332. X/* The LaserWriter's VMstate is saved to avoid choking on multiple */
  1333. X/* subsequent printjobs. This is neccesary because the LW does not notice */
  1334. X/* end-of-file condition. 08/06/87 --- axel@coma.uucp */
  1335. X#ifdef VMSAVE
  1336. X    fprintf(postr, "/vmstat save def\n");
  1337. X#endif VMSAVE
  1338. X
  1339. X    ptab = pcom0tab;
  1340. X    while(*ptab)
  1341. X        fprintf(postr, "%s\n", *ptab++);
  1342. X#ifndef GEMPRINT
  1343. X    fprintf(postr, "%s\n", ptstr[papertype]);
  1344. X#endif GEMPRINT
  1345. X    if(rotation != PD_ROTATION)
  1346. X        fprintf(postr, "%.1f rotate\n", rotation);
  1347. X    if(scale != 1.0 && scale != 0.0)
  1348. X        fprintf(postr, "%.4f dup scale\n", scale);
  1349. X    ptab = pcom1tab;
  1350. X    while(*ptab)
  1351. X        fprintf(postr, "%s\n", *ptab++);
  1352. X#if    VERBOSE
  1353. X    fprintf(postr, "/jobname (%s) def\n", jobname);
  1354. X    fprintf(postr, "userdict /jobname jobname put\n");
  1355. X    fprintf(postr, "( :: '%s' :: job starts\\n) ps\n", jobname);
  1356. X#endif    VERBOSE
  1357. X    fprintf(postr, "%s\n", manualfeed ? "mf" : "af");
  1358. X}
  1359. X
  1360. endinit()
  1361. X{
  1362. X    /* this save is for the restore/save pairs in page */
  1363. X    fprintf(postr, "\nsave\n");
  1364. X    /* all variable assignments are now local to a page */
  1365. X
  1366. X    /* initialise current path - move to top of page */
  1367. X    fprintf(postr, "home\n");
  1368. X    fprintf(postr, "%%%%EndProlog\n");
  1369. X}
  1370. X
  1371. pch(ch)
  1372. int    ch;
  1373. X{
  1374. X    if(ch < ' ' || ch > '~')
  1375. X        fprintf(postr, "\\%03o", ch);
  1376. X    else
  1377. X    {
  1378. X        if(ch == '(' || ch == ')' || ch == '\\')
  1379. X            putc('\\', postr);
  1380. X        putc(ch, postr);
  1381. X    }
  1382. X}
  1383. X
  1384. pcommfinish(pages, fonts)
  1385. int pages;
  1386. char *fonts;
  1387. X{
  1388. X    fprintf(postr, "\n%%%%Trailer\n");
  1389. X#if    VERBOSE
  1390. X    fprintf(postr, "jobname ps (: Job finished:\\n) ps\n");
  1391. X    fprintf(postr, "(\\ttime (s) = ) ps usertime stm sub 1000 div ==\n");
  1392. X    fprintf(postr, "(\\tpages = ) ps statusdict begin pagecount end pgc sub == flush\n");
  1393. X    if(pages >= 0)
  1394. X        fprintf(postr, "%%%%Pages: %d\n", pages);
  1395. X#endif    VERBOSE
  1396. X    if(fonts)
  1397. X        fprintf(postr, "%%%%DocumentFonts: %s\n");
  1398. X
  1399. X/* This is the complementary statement for the beginnig of pcomminit */
  1400. X/* The LaserWriter's VMstate is reset to avoid choking on multiple */
  1401. X/* subsequent printjobs. This is neccesary because the LW does not notice */
  1402. X/* end-of-file condition. 08/06/87 --- axel@coma.uucp */
  1403. X#ifdef VMSAVE
  1404. X    fprintf (postr, 
  1405. X              "count { pop } repeat %% a little cleanup is necessary\n");
  1406. X    fprintf (postr, "vmstat restore\n");
  1407. X#endif VMSAVE
  1408. X}
  1409. X
  1410. X#if    VERBOSE
  1411. char *
  1412. getuser()
  1413. X{
  1414. X    char        *lname;
  1415. X    static char    username[100];
  1416. X#if    AUSAM
  1417. X    char        sbuf[SSIZ];
  1418. X    struct pwent    pe;
  1419. X    extern int    getpwlog();
  1420. X
  1421. X    pe.pw_limits.l_uid = getuid();
  1422. X    if(getpwlog(&pe, sbuf, sizeof(sbuf)) == PWERROR)
  1423. X        lname = (char *)0;
  1424. X    else
  1425. X        lname = pe.pw_strings[LNAME];
  1426. X    pwclose();
  1427. X    if(lname == (char *)0)
  1428. X        lname = "?";
  1429. X    strcpy(username, lname);
  1430. X
  1431. X#else    /* ! AUSAM */
  1432. X    extern    char        *getlogin();
  1433. X    extern    struct passwd    *getpwuid();
  1434. X    struct    passwd        *pwdp;
  1435. X
  1436. X    if ( ( lname = getlogin() ) != NULL )
  1437. X        strcpy( username, lname );
  1438. X    else
  1439. X    {
  1440. X        if ( ( pwdp = getpwuid( getuid() ) ) == (struct passwd *)0 )
  1441. X            sprintf( username, "User%d", getuid() );
  1442. X        else
  1443. X            strcpy( username, pwdp->pw_name );
  1444. X    }
  1445. X#endif    /* ! AUSAM */
  1446. X    strcat(username, "@");
  1447. X    strcat(username, systemid());
  1448. X    return(username);
  1449. X}
  1450. X
  1451. char *
  1452. systemid()
  1453. X{
  1454. X    static char    sysname[100] = "";
  1455. X
  1456. X#if    UNSW
  1457. X    getaddr(G_SYSNAME, sysname);
  1458. X#endif    UNSW
  1459. X
  1460. X#if    BSD
  1461. X    gethostname( sysname, sizeof(sysname) );
  1462. X#endif    BSD
  1463. X
  1464. X#if    SYSV
  1465. X    struct utsname    un;
  1466. X
  1467. X    uname(&un);
  1468. X    strcpy(sysname, un.nodename);
  1469. X#endif    SYSV
  1470. X
  1471. X    return(sysname);
  1472. X}
  1473. X#endif    VERBOSE
  1474. END_OF_FILE
  1475. if test 7314 -ne `wc -c <'./tpscript/pcom.c'`; then
  1476.     echo shar: \"'./tpscript/pcom.c'\" unpacked with wrong size!
  1477. fi
  1478. # end of './tpscript/pcom.c'
  1479. fi
  1480. if test -f './tpscript/sfont2.c' -a "${1}" != "-c" ; then 
  1481.   echo shar: Will not clobber existing file \"'./tpscript/sfont2.c'\"
  1482. else
  1483. echo shar: Extracting \"'./tpscript/sfont2.c'\" \(6079 characters\)
  1484. sed "s/^X//" >'./tpscript/sfont2.c' <<'END_OF_FILE'
  1485. X/*
  1486. X * sfont2.c
  1487. X * routines for manipulating special font 2 (the characters generated
  1488. X * specifically to match troff requirements - because kludging the available
  1489. X * bracket chars could never be made to work completely properly)
  1490. X */
  1491. X
  1492. X#include    "tpscript.h"
  1493. X
  1494. X#include    "sfont2defs.h"
  1495. X
  1496. struct spcdefs {
  1497. X    short    s2_index;    /* index in encoding structure == value in width tables */
  1498. X    short    s2_width;    /* width of char as in width tables */
  1499. X    char    *s2_name;    /* troff 2(?)-char name */
  1500. X    char    *s2_def;    /* the postscript definition to build the char */
  1501. X};
  1502. X
  1503. X        /*
  1504. X         * if chars are wider than this then you cannot use the
  1505. X         * default C.setC procedure for calling setcachedevice
  1506. X         * This comes about because, while I could just call
  1507. X         * setcachedevice with the values in FontBBox, I assume that
  1508. X         * I will save caching memory if i dont use a value which is
  1509. X         * twice as big as I really need for most chars.
  1510. X         * ... But do I really save anything since the definition is
  1511. X         * now a bit bigger? - probably I do, since the space defined
  1512. X         * by the bounding box at 10 pt is about 2400 pixels
  1513. X         * (~ 300 bytes)
  1514. X         */
  1515. X#define    DFLT_CACHE_WIDTH    50
  1516. X
  1517. X    /*
  1518. X     * note - I really should look up the width in the width tables and
  1519. X     * just use that but when we run s2init() we havent read in the
  1520. X     * tables yet - and while about it i should probably read in the
  1521. X     * index value as well.
  1522. X     */
  1523. X
  1524. typedef    struct    spcdefs    S2DEF;
  1525. X
  1526. S2DEF    s2defs[]  = {
  1527. X    { 0101, 50, "bv", "C.bv" },
  1528. X    { 0102, 50, "lt", DEF_lt },
  1529. X    { 0103, 50, "lk", DEF_lk },
  1530. X    { 0104, 50, "lb", DEF_lb },
  1531. X    { 0105, 50, "rt", DEF_rt },
  1532. X    { 0106, 50, "rk", DEF_rk },
  1533. X    { 0107, 50, "rb", DEF_rb },
  1534. X    { 0110, 50, "lc", DEF_lc },
  1535. X    { 0111, 50, "lf", DEF_lf },
  1536. X    { 0112, 50, "rc", DEF_rc },
  1537. X    { 0113, 50, "rf", DEF_rf },
  1538. X    { 0114, 0, "br",  DEF_br },
  1539. X    { 0115, 50, "rn", DEF_rn },
  1540. X    { 0116, 100, "ci", DEF_ci },
  1541. X    { 0117, 17,  "||", DEF_sp_6 },
  1542. X    { 0120, 8,   "^^", DEF_sp_12 },
  1543. X    { 0121, 80,  "r1", DEF_r1 },
  1544. X    { 0122, 80,  "r2", DEF_r2 },
  1545. X    { 0, 0,    "",   "" }
  1546. X};
  1547. X#define    NUM_S2DEFS    (sizeof s2defs/sizeof(S2DEF) -1)
  1548. X
  1549. X    /*
  1550. X     * bracket font initialisation
  1551. X     */
  1552. char    *bf_0init[] = {
  1553. X    "/BracketFontDict 9 dict def /$workingdict 10 dict def",
  1554. X    "BracketFontDict begin",
  1555. X        /* locally defined font */
  1556. X    "/FontType 3 def",
  1557. X        /* give it a name like the built-in fonts */
  1558. X    "/FontName (Bracket) cvn def",
  1559. X        /* the standard matrix for font definitions */
  1560. X    "/FontMatrix [ 0.001 0 0 0.001 0 0] def",
  1561. X    "/FontBBox [ -50 -250 1000 1000 ] def",
  1562. X        /* will be a sparse array so fill initally with .notdef */
  1563. X    "/Encoding 256 array def 0 1 255 { Encoding exch /.notdef put } for",
  1564. X    "Encoding",
  1565. X    (char *) 0 };
  1566. X        /* at this point we put the real encoding and the procedures for
  1567. X        * building the chars
  1568. X        */
  1569. X
  1570. X        /*
  1571. X         * predefined common routines for inclusion in CharProcs
  1572. X         */
  1573. char    *bf_CPinit[] = {
  1574. X            /*
  1575. X             * define setcachedevice with default width passed
  1576. X             * as argument (on stack)
  1577. X             */
  1578. X    "/setC { 0 -50 -250 500 1000 setcachedevice} def",
  1579. X            /*
  1580. X             * common stuff for solid vert bar (\(bv)
  1581. X             * also used for floor and ceilings
  1582. X             */
  1583. X    "/C.bv {220 -250 moveto 0 1000 rlineto",
  1584. X        "60 0 rlineto 0 -1000 rlineto fill } def",
  1585. X            /*
  1586. X             * stuff for horiz bar for ceiling
  1587. X             * X coord passed as arg
  1588. X             */
  1589. X    "/C.barc { 750 moveto 180 0 rlineto 0 -60 rlineto -180 0 rlineto fill } def",
  1590. X            /*
  1591. X             * stuff for horiz bar for floor
  1592. X             */
  1593. X    "/C.barf { -250 moveto 180 0 rlineto 0 60 rlineto -180 0 rlineto fill } def",
  1594. X            /*
  1595. X             * common routine for drawing the end parts of brackets
  1596. X             * e.g. \(lt, \(lb
  1597. X             * start with starting x,y on stack
  1598. X             * draw line and then curve to tip
  1599. X             */
  1600. X    "/C.brk.end { 1 setlinewidth moveto rlineto rcurveto",
  1601. X            /* back to start, over by width of line */
  1602. X            /* draw line and then curve to near tip */
  1603. X        "reversepath 60 0 rlineto rlineto rcurveto fill } def",
  1604. X
  1605. X            /*
  1606. X             * set the linewidth rounded to the nearest pixel
  1607. X             * We need a dummy y entry as well but ignore it.
  1608. X             * The reason for using the X rounded value is only
  1609. X             * relevant when ( x-scale != y-scale ):
  1610. X             * since troff keeps char width constant and scales
  1611. X             * the height up/down, we also scale relative to the
  1612. X             * width.
  1613. X             */
  1614. X    "/C.setl {dup dtransform exch round exch idtransform pop setlinewidth } def",
  1615. X
  1616. X    (char *) 0 };
  1617. X
  1618. X#define    N_CP_PROCS    6    /* number of extra common procs */
  1619. X
  1620. X        /*
  1621. X         * the mandatory BuildChar routine for the font description
  1622. X         */
  1623. char    *bf_1init[] = {
  1624. X    "/BuildChar",
  1625. X    "{",
  1626. X    "    $workingdict begin",
  1627. X    "    /charcode exch def",
  1628. X    "    /fontdict exch def",
  1629. X    "    fontdict /CharProcs get begin",
  1630. X    "    fontdict /Encoding get",
  1631. X    "    charcode get load",
  1632. X    "    gsave",
  1633. X    "    0 setlinecap 0 setgray newpath",
  1634. X    "    exec",
  1635. X    "    grestore",
  1636. X    "    end end",
  1637. X    "} def end",
  1638. X    "/BracketFont BracketFontDict definefont pop",
  1639. X    (char *) 0 };
  1640. X
  1641. X        /*
  1642. X         * setup the definitions for building our own special font
  1643. X         * for the characters that the laserwriter does not do
  1644. X         * properly
  1645. X         */
  1646. s2init()
  1647. X{
  1648. X    register    char    **ptab;
  1649. X    register    S2DEF    *s2p;
  1650. X
  1651. X    ptab = bf_0init;
  1652. X    while(*ptab)
  1653. X        fprintf(postr, "%s\n", *ptab++);
  1654. X            /*
  1655. X             * now put the entries in the encoding table
  1656. X             */
  1657. X    for ( s2p = &s2defs[0] ; s2p->s2_index != 0 ; s2p++ )
  1658. X        fprintf( postr, "dup %d /C%s put\n",
  1659. X                s2p->s2_index, s2p->s2_name);
  1660. X            /*
  1661. X             * define the CharProcs dictionary which contains
  1662. X             * the procedures required by BuildChar to construct
  1663. X             * the characters
  1664. X             */
  1665. X    fprintf( postr, "pop\n/CharProcs %d dict dup begin\n",
  1666. X            NUM_S2DEFS + N_CP_PROCS );
  1667. X
  1668. X    ptab = bf_CPinit;
  1669. X    while(*ptab)
  1670. X        fprintf(postr, "%s\n", *ptab++);
  1671. X
  1672. X    for ( s2p = &s2defs[0] ; s2p->s2_index != 0 ; s2p++ )
  1673. X    {
  1674. X        if ( s2p->s2_width == DFLT_CACHE_WIDTH )
  1675. X            fprintf( postr, "/C%s {\n%d setC\n%s\n} def\n",
  1676. X                s2p->s2_name,
  1677. X                (int)(s2p->s2_width * respunits),
  1678. X                    /* this is unwise because it assumes
  1679. X                     * unitwidth 10 in DESC file
  1680. X                     */
  1681. X                s2p->s2_def);
  1682. X        else
  1683. X            fprintf( postr,
  1684. X                "/C%s {\n%d 0 -50 -250 %d 1000 setcachedevice\n%s\n} def\n",
  1685. X                s2p->s2_name,
  1686. X                (int)(s2p->s2_width * respunits),
  1687. X                (int)(s2p->s2_width * respunits),
  1688. X                s2p->s2_def);
  1689. X    }
  1690. X    fputs( "end def\n", postr);
  1691. X    ptab = bf_1init;
  1692. X    while(*ptab)
  1693. X        fprintf(postr, "%s\n", *ptab++);
  1694. X}
  1695. X
  1696. END_OF_FILE
  1697. if test 6079 -ne `wc -c <'./tpscript/sfont2.c'`; then
  1698.     echo shar: \"'./tpscript/sfont2.c'\" unpacked with wrong size!
  1699. fi
  1700. # end of './tpscript/sfont2.c'
  1701. fi
  1702. echo shar: End of archive 4 \(of 5\).
  1703. cp /dev/null ark4isdone
  1704. MISSING=""
  1705. for I in 1 2 3 4 5 ; do
  1706.     if test ! -f ark${I}isdone ; then
  1707.     MISSING="${MISSING} ${I}"
  1708.     fi
  1709. done
  1710. if test "${MISSING}" = "" ; then
  1711.     echo You have unpacked all 5 archives.
  1712.     rm -f ark[1-9]isdone
  1713. else
  1714.     echo You still need to unpack the following archives:
  1715.     echo "        " ${MISSING}
  1716. fi
  1717. ##  End of shell archive.
  1718. exit 0
  1719.